// Copyright (c) 2024 刻BITTER
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.


#pragma once

/**
 * @brief   包含了用于AVR 单片机的通用引脚定义和操作，依赖Arduino 库
 */

#include <Arduino.h>

#include "ioxx_common.hpp"

namespace ioxx {

    class Pin {
       private:
        uint8_t _pin;

       public:
        constexpr Pin(uint8_t pin) :
            _pin(pin) {}

        void set() const {
            digitalWrite(_pin, 1);
        }

        void set(bool level) const {
            digitalWrite(_pin, level);
        }

        void clr() const {
            digitalWrite(_pin, 0);
        }

        auto get() const {
            return digitalRead(_pin);
        }

        void toggle() const {
#ifdef STM32_CORE_VERSION  // STM32DUINO 有digitalToggle API
            digitalToggle(_pin);
#else
            digitalWrite(_pin, !digitalRead(_pin));
#endif
        }


        void config_mode_input() const {
            pinMode(_pin, INPUT);
        }


        void config_mode_input_pullup() const {
            pinMode(_pin, INPUT_PULLUP);
        }


        void config_mode_output() const {
            pinMode(_pin, OUTPUT);
        }

        /**
         * @brief 可以隐式将 Pin 对象反向转换回引脚编号
         *
         * @return uint8_t
         */
        operator uint8_t() const {
            return _pin;
        }
    };


    inline void setpin(Pin p) {
        p.set();
    }


    inline void clrpin(Pin p) {
        p.clr();
    }


    inline auto getpin(Pin p) {
        return p.get();
    }


    inline void toggle_pin(Pin p) {
        p.toggle();
    }

}  // namespace ioxx